local onchangefn = {}
if task_data then
	for k, v in pairs(task_data) do
		onchangefn[k] = function(self, val)
			self.net_data[k]:set(val)
		end
	end
end

onchangefn.coin = function(self, val)
	self.net_data.coin:set(val)
end

local TaskData = Class(function(self, inst) 
    self.inst = inst
    --网络数据，客主机需要并保存
    self.net_data = {
    	coin = net_shortint(inst.GUID, "taskdata.coin", "taskcoindirty")
    }
    self:Init()
    self.coin = 0

    --主机数据，需保存
    self.tumbleweednum = 0
    self.eat_types = {}
    self.shadowboss_killed = {}

    --主机临时数据，无需保存
    self.killed_temp = {} --临时存储击杀数据，防止重复击杀判定

    self.complete_time = nil
    self.killboss = 0
    self.collect = 0
end,
nil,
onchangefn)

function TaskData:Init()
	if task_data then
		local inst = self.inst
		for k, v in pairs(task_data) do
			local need = v.need or 1
			if need < 255 then 
				self.net_data[k] = net_byte(inst.GUID, k)
			elseif need < 32767 then
				self.net_data[k] = net_shortint(inst.GUID, k)
			else
				self.net_data[k] = net_int(inst.GUID, k)
			end
			self[k] = 0
		end
	end
	self:AllCompletedCheck()
end

function TaskData:OnSave()
	local data = {}
	if task_data then
		for k, v in pairs(task_data) do
			data[k] = self[k] or 0
		end
	end
	data.coin = self.coin or 0
	data.tumbleweednum = self.tumbleweednum or 0
	data.eat_types = self.eat_types or {}
	data.shadowboss_killed = self.shadowboss_killed or {}
	data.complete_time = self.complete_time or nil
	data.killboss = self.killboss or 0
	data.collect = self.collect or 0
	return data
end

function TaskData:OnLoad(data)
	for k, v in pairs(data) do
		self[k] = v or 0
	end	
end

function TaskData:AddCollectTask()
	self.collect = self.collect + 1
	if self.collect % 5 == 0 then
		SpawnPrefab("seffc").entity:SetParent(self.inst.entity)
		TheNet:Announce(self.inst:GetDisplayName().." 累积完成收集任务 "..self.collect.." 次，奖励 5", self.inst.entity)
		self.inst.components.purchase:CoinDoDelta(5)
	end
end

function TaskData:KillBoss()
	self.killboss = self.killboss + 1
	if self.killboss % 5 == 0 then
		SpawnPrefab("seffc").entity:SetParent(self.inst.entity)
		TheNet:Announce(self.inst:GetDisplayName().." 累积击杀boss "..self.killboss.." 次，奖励 5", self.inst.entity)
		self.inst.components.purchase:CoinDoDelta(5)
	end
end

function TaskData:AddOne(taskname)
	if self[taskname] ~= nil and task_data[taskname] ~= nil then
		local task_info = task_data[taskname]
		local task_text = task_info.name
		local reward = task_info.reward or 1
		local need = task_info.need or 1
		local hide = task_info.hide or false
        if self[taskname] >= need then 
            self[taskname] = need
            return
        end
        self[taskname] = self[taskname] + 1
        if self[taskname] >= need then
            self[taskname] = need
            self:Completed(taskname)
        end
    end
end

function TaskData:AddMulti(taskname, num)
	if self[taskname] ~= nil and task_data[taskname] ~= nil then
		local task_info = task_data[taskname]
		local task_text = task_info.name
		local reward = task_info.reward or 1
		local need = task_info.need or 1
		local hide = task_info.hide or false
        if self[taskname] >= need then 
            self[taskname] = need
            return
        end
        self[taskname] = self[taskname] + num
        if self[taskname] >= need then
            self[taskname] = need
            self:Completed(taskname)
        end
    end
end

function TaskData:Completed(taskname)
	local inst = self.inst
	local task_info = task_data[taskname]
	if task_info == nil then return end --防止代码崩档 

	local task_text = task_info.name
	local reward = task_info.reward or 1
	local desc = task_info.desc
	local need = task_info.need or 1
	local tag = (task_info.hide and "*隐藏任务*" or "") or ""
	SpawnPrefab("seffc").entity:SetParent(inst.entity)

	self[taskname] = need

	self:CoinDoDelta(task_info.reward or 1) --此处暂时保留数值
	self.inst.components.purchase:CoinDoDelta(task_info.reward or 1)  --真实coin数量
	inst:DoTaskInTime(.3,function() 
		self:AllCompletedCheck()
        inst:PushEvent("taskcompleted", {taskname=taskname})
    end) 

	local extra_annouce_str = ""
    if inst:HasTag("worker_1") then 
    	if inst.components.playerlevel then 
    		inst.components.playerlevel:AddXp(100)
    		extra_annouce_str = " 【工薪1】额外奖励 100 经验"
    		inst.components.skilldata:RandomSkillLevelUp()
    	end
    end
    if inst:HasTag("worker_2") then 
    	if inst.components.purchase then 
    		local extra_coin = math.random(5)
    		inst.components.purchase:CoinDoDelta(extra_coin)
    		extra_annouce_str = " 【工薪2】额外奖励 "..extra_coin.." 财富"
    		inst.components.skilldata:RandomSkillLevelUp()
    	end
    end

    local desc_str = string.format(desc, " "..need.." ")
	local annouce_str = string.format("%s %s %s 完成任务【%s】 奖励 %d", tag, inst:GetDisplayName(), desc_str, task_text, reward) 
	annouce_str = annouce_str..extra_annouce_str
	TheNet:Announce(annouce_str, inst.entity)
end

function TaskData:AllCompletedCheck()
	if self.all ~= 1 then
		for k,v in pairs(task_data) do
			if k ~= "all" and not v.hide then
				local need = v.need or 1
				if self[k] < need then
					return false
				end
			end
		end
		self:AddOne('all')
		self.complete_time = os.date("%Y-%m-%d %X")
		return true
	else
		return true
	end
end

--测试专用
function TaskData:GrantAll(pwd)
	--添加简单的参数防止误用
    if pwd==nil or pwd ~= "123456" then return end
	for k,v in pairs(task_data) do
        if k ~= "all" and not v.hide then
        	local need = v.need or 1
            if self[k] < need then
                self[k] = need
            end
        end
    end
	--...
	self:AllCompletedCheck()
end

function TaskData:CoinDoDelta(value)
	self.coin = self.coin + value
	if self.coin < 0 then self.coin = 0 end --防止数据异常
end

return TaskData